#include <FileManager.h>

void
File_nextI :: ice_response(const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& bytes)
{
  Lock sync(*this);
  Ice::ByteSeq(bytes.first, bytes.second).swap(_bytes);
  _done = true;
  notify();
}

void
File_nextI :: ice_exception(const ::Ice::Exception& ex)
{
  Lock sync(*this);
  _exception.reset(ex.ice_clone());
  _done = true;
  notify();
}

void
File_nextI :: getData(::Ice::ByteSeq& bytes)
{
  Lock sync(*this);
  while (!_done) {
    wait();
  }
  _done = false;
  if (_exception.get()) {
    auto_ptr<Ice::Exception> ex = _exception;
    _bytes.clear();
    ex->ice_throw();
  }
  bytes.swap(_bytes);
}

int FileManager::getFile()
{
  FILE* fp = fopen(_scene.c_str(), _flags.c_str());
  int len = 1000 * 1024;
  int rc = EXIT_SUCCESS;
  int offset = 0;
  File_nextIPtr curr, next;
  Ice::ByteSeq bytes;

  fseek(fp, _offset, SEEK_SET);
  
  for (;;) {
    if (!curr) {
      curr = new File_nextI;
      next = new File_nextI;
      _file->next_async(curr);
    }
    else {
      swap(curr, next);
    }
    _file->next_async(next);
    curr->getData(bytes);
    if (bytes.empty()) {
       break;
    }
    if (fwrite(&bytes[0], 1, bytes.size(), fp)
	!= bytes.size()) {
      cerr << "error writing: " << strerror(errno) << endl;
      rc = EXIT_FAILURE;
    }
    else
    offset += bytes.size(); 
  }
  
  fclose(fp);

  return rc;
}

string FileManager::getFileName()
{
  return _scene;
}
